Dental Application


Problem 1
Design a database to manage a dental practice.

dental.sql
USE master;
GO

IF EXISTS(SELECT * FROM sysdatabases WHERE name='dental')
BEGIN
     RAISERROR('Dropping existing dental database...', 0, 1)
     DROP DATABASE dental;
END
GO

CREATE DATABASE dental;
GO

USE dental;
GO

IF db_name() <>'dental'
BEGIN
     RAISERROR('Use database failed...', 22, 127) WITH LOG
     DROP DATABASE dental;
END
GO

CREATE TABLE userx
(
     userx_id INT IDENTITY NOT NULL PRIMARY KEY,
     username VARCHAR(15) UNIQUE NOT NULL,
     first_name VARCHAR(30) NOT NULL,
     last_name VARCHAR(30) NOT NULL,
     passwordx VARCHAR(15) NOT NULL,
     email VARCHAR(30) NOT NULL CONSTRAINT userx_email_ck
          CHECK (email LIKE '%@%'),
     is_active BIT NOT NULL,
     has_access_patient_info BIT NOT NULL, -- Table: patient
     has_access_users BIT NOT NULL, -- Table: userx
     has_access_payments BIT NOT NULL, -- Table: transactionx with transation_type = Payment, Discount, or Consolidation
     has_access_patient_chart BIT NOT NULL, -- Table: transactionx with transation_type = Dental procedure
     has_access_dental_procedure_setup BIT NOT NULL -- Table: dental_procedure
);
GO
INSERT INTO userx (username, first_name, last_name, passwordx,
email, is_active, has_access_patient_info, has_access_users,
has_access_payments, has_access_patient_chart, has_access_dental_procedure_setup)
VALUES ('tommy', 'Tom', 'Martinez', 'abc', 'tommy@live.com',
1, 1, 1, 1, 1, 1);

INSERT INTO userx (username, first_name, last_name, passwordx,
email, is_active, has_access_patient_info, has_access_users,
has_access_payments, has_access_patient_chart, has_access_dental_procedure_setup)
VALUES ('july', 'Julia', 'Williams', 'hola', 'julia@yahoo.com',
1, 1, 1, 1, 0, 0);

INSERT INTO userx (username, first_name, last_name, passwordx,
email, is_active, has_access_patient_info, has_access_users,
has_access_payments, has_access_patient_chart, has_access_dental_procedure_setup)
VALUES ('marco', 'Mark', 'Perez', '123', 'mark91@hotmail.com',
1, 1, 0, 1, 0, 0);
GO

CREATE TABLE dbo.tooth
(
     tooth_id INT NOT NULL CONSTRAINT tooth_pk PRIMARY KEY IDENTITY,
     tooth_code VARCHAR(2) UNIQUE NOT NULL,
     position SMALLINT NOT NULL,
     is_adult_tooth BIT NOT NULL,
     is_top_tooth BIT NOT NULL,
     descr VARCHAR(32) NOT NULL,
     is_molar BIT NOT NULL -- Es muela?
)
GO
-- This tooth is used for transactions without tooths
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('0', 0, 0, 0, 'No tooth', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('1', 1, 1, 1, '3rd molar (wisdow tooth)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('2', 2, 1, 1, '2nd molar (12-yr. molar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('3', 3, 1, 1, '1st molar (6-yr. molar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('4', 4, 1, 1, '2nd bicuspid (2nd premolar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('5', 5, 1, 1, '1st bicuspid (1st premolar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('6', 6, 1, 1, 'cuspid (canine/eye tooth)', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('7', 7, 1, 1, 'lateral incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('8', 8, 1, 1, 'central incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('9', 9, 1, 1, 'central incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('10', 10, 1, 1, 'lateral incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('11', 11, 1, 1, 'cuspid (canine/eye tooth)', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('12', 12, 1, 1, '1st bicuspid (1st premolar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('13', 13, 1, 1, '2nd bicuspid (2nd premolar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('14', 14, 1, 1, '1st molar (6-yr. molar)', 1)
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('15', 15, 1, 1, '2nd molar (12-yr. molar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('16', 16, 1, 1, '3rd molar (wisdow tooth)', 1);
GO
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('17', 17, 1, 0, '3rd molar (wisdow tooth)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('18', 18, 1, 0, '2nd molar (12-yr. molar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('19', 19, 1, 0, '1st molar (6-yr. molar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('20', 20, 1, 0, '2nd bicuspid (2nd premolar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('21', 21, 1, 0, '1st bicuspid (1st premolar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('22', 22, 1, 0, 'cuspid (canine/eye tooth)', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('23', 23, 1, 0, 'lateral incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('24', 24, 1, 0, 'central incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('25', 25, 1, 0, 'central incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('26', 26, 1, 0, 'lateral incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('27', 27, 1, 0, 'cuspid (canine/eye toorh)', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('28', 28, 1, 0, '1st bicuspid (1st premolar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('29', 29, 1, 0, '2nd bicuspid (2nd premolar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('30', 30, 1, 0, '1st molar (6-yr. molar)', 1)
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('31', 31, 1, 0, '2nd molar (12-yr. molar)', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('32', 32, 1, 0, '3rd molar (wisdow tooth)', 1);
GO
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('A', 4, 0, 1, 'second molar', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('B', 5, 0, 1, 'first molar', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('C', 6, 0, 1, 'canine (cuspid)', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('D', 7, 0, 1, 'lateral incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('E', 8, 0, 1, 'central incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('F', 9, 0, 1, 'central incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('G', 10, 0, 1, 'lateral incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('H', 11, 0, 1, 'canine (cuspid)', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('I', 12, 0, 1, 'first molar', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('J', 13, 0, 1, 'second molar', 1);
GO
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('K', 20, 0, 0, 'second molar', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('L', 21, 0, 0, 'first molar',1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('M', 22, 0, 0, 'canine (cuspid)', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('N', 23, 0, 0, 'lateral incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('O', 24, 0, 0, 'central incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('P', 25, 0, 0, 'central incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('Q', 26, 0, 0, 'lateral incisor', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('R', 27, 0, 0, 'canine (cuspid)', 0);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('S', 28, 0, 0, 'first molar', 1);
INSERT INTO tooth (tooth_code, position, is_adult_tooth, is_top_tooth, descr, is_molar) VALUES ('T', 29, 0, 0, 'second molar', 1);
GO

CREATE TABLE patient
(
     patient_id INT IDENTITY NOT NULL PRIMARY KEY,
     first_name VARCHAR(30) NOT NULL,
     last_name VARCHAR(30) NOT NULL,
     birth_date DATE NOT NULL,
     email VARCHAR(64) NOT NULL CONSTRAINT patient_email_ck CHECK (email LIKE '%@%')
)
GO
INSERT INTO patient (first_name, last_name, birth_date, email)
VALUES ('Rafael', 'Smith', 'April 28, 1990', 'rafa@gmail.com');
INSERT INTO patient (first_name, last_name, birth_date, email)
VALUES ('Jose', 'Macias', 'February 22, 1987', 'jose@gmail.com');
INSERT INTO patient (first_name, last_name, birth_date, email)
VALUES ('Mary', 'Thompson', 'September 9, 1965', 'mary2000@outlook.com');
GO

CREATE TABLE dental_procedure
(
     dental_procedure_id INT IDENTITY NOT NULL PRIMARY KEY,
     descr VARCHAR(30) NOT NULL,
     estimated_cost MONEY NOT NULL,
     --_____________________________ Root
     root_line_color_red INT NOT NULL,
     root_line_color_green INT NOT NULL,
     root_line_color_blue INT NOT NULL,
     --
     root_fill_color_red INT NOT NULL,
     root_fill_color_green INT NOT NULL,
     root_fill_color_blue INT NOT NULL,
     --_____________________________ Body
     body_line_color_red INT NOT NULL,
     body_line_color_green INT NOT NULL,
     body_line_color_blue INT NOT NULL,
     --
     body_fill_color_red INT NOT NULL,
     body_fill_color_green INT NOT NULL,
     body_fill_color_blue INT NOT NULL
)
GO
-- This proceduce is used for: Payment, Discount and Consolidation
INSERT INTO dental_procedure (descr, estimated_cost,
root_line_color_red, root_line_color_green, root_line_color_blue,
root_fill_color_red, root_fill_color_green, root_fill_color_blue,
body_line_color_red, body_line_color_green, body_line_color_blue,
body_fill_color_red, body_fill_color_green, body_fill_color_blue)
VALUES ('None', 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
INSERT INTO dental_procedure (descr, estimated_cost,
root_line_color_red, root_line_color_green, root_line_color_blue,
root_fill_color_red, root_fill_color_green, root_fill_color_blue,
body_line_color_red, body_line_color_green, body_line_color_blue,
body_fill_color_red, body_fill_color_green, body_fill_color_blue)
VALUES ('Extraction', 90.0, 255, 0, 0, 255, 180, 180, 255, 0, 0, 255, 180, 180);
INSERT INTO dental_procedure (descr, estimated_cost,
root_line_color_red, root_line_color_green, root_line_color_blue,
root_fill_color_red, root_fill_color_green, root_fill_color_blue,
body_line_color_red, body_line_color_green, body_line_color_blue,
body_fill_color_red, body_fill_color_green, body_fill_color_blue)
VALUES ('Endodoncy', 556.20, 0, 180, 0, 180, 255, 180, 0, 0, 255, 180, 180, 255);
INSERT INTO dental_procedure (descr, estimated_cost,
root_line_color_red, root_line_color_green, root_line_color_blue,
root_fill_color_red, root_fill_color_green, root_fill_color_blue,
body_line_color_red, body_line_color_green, body_line_color_blue,
body_fill_color_red, body_fill_color_green, body_fill_color_blue)
VALUES ('Filling', 89.50, 180, 180, 0, 255, 255, 180, 255, 180, 255, 255, 180, 255);
GO

CREATE TABLE transaction_type
(
     transaction_type_id INT IDENTITY NOT NULL PRIMARY KEY,
     descr VARCHAR(32) NOT NULL
);
GO
INSERT INTO transaction_type (descr) VALUES ('Dental Procedure');
INSERT INTO transaction_type (descr) VALUES ('Payment');
GO

CREATE TABLE transactionx
(
     transaction_id INT IDENTITY NOT NULL PRIMARY KEY,
     transaction_type_id INT NOT NULL REFERENCES transaction_type(transaction_type_id),
     transaction_date DATE NOT NULL DEFAULT GETDATE(),
     patient_id INT NOT NULL REFERENCES patient(patient_id),
     dental_procedure_id INT NOT NULL REFERENCES dental_procedure(dental_procedure_id),
     tooth_id INT NOT NULL REFERENCES tooth(tooth_id),
     amount MONEY NOT NULL,
     userx_id INT NOT NULL REFERENCES userx(userx_id),
     comment VARCHAR(100) NULL
);
GO
-- DENTAL PROCEDURE
INSERT INTO transactionx (transaction_type_id, patient_id, dental_procedure_id,
tooth_id, amount, userx_id) VALUES (1, 1, 2, 32, 100.0, 1);
-- PAYMENT
INSERT INTO transactionx (transaction_type_id, patient_id, dental_procedure_id,
tooth_id, amount, userx_id) VALUES (2, 1, 1, 1, 40.0, 2);
-- PAYMENT
INSERT INTO transactionx (transaction_type_id, patient_id, dental_procedure_id,
tooth_id, amount, userx_id) VALUES (2, 1, 1, 1, 60.0, 3);
-- DENTAL PROCEDURE
INSERT INTO transactionx (transaction_type_id, patient_id, dental_procedure_id,
tooth_id, amount, userx_id) VALUES (1, 2, 2, 6, 500.0, 1);
-- DENTAL PROCEDURE
INSERT INTO transactionx (transaction_type_id, patient_id, dental_procedure_id,
tooth_id, amount, userx_id) VALUES (1, 2, 3, 7, 411.0, 1);
GO

CREATE FUNCTION to_yesno
(
@input BIT
)
RETURNS VARCHAR(4)
AS
BEGIN
DECLARE @result AS VARCHAR(4);
IF (@input = 1)
          SET @result = 'yes';
     ELSE
          SET @result = 'no';
RETURN (@result);
END
GO

CREATE FUNCTION to_access
(
@input BIT
)
RETURNS VARCHAR(8)
AS
BEGIN
DECLARE @result AS VARCHAR(8);
IF (@input = 1)
          SET @result = 'access';
     ELSE
          SET @result = 'deny';
RETURN (@result);
END
GO

CREATE VIEW vw_dental_procedure
AS
SELECT dental_procedure_id, descr, estimated_cost,
'('+ CAST(body_line_color_red AS VARCHAR) + ', ' + CAST(body_line_color_green AS VARCHAR) + ', ' + CAST(body_line_color_blue AS VARCHAR) + ')' AS body_line_color,
'('+ CAST(body_fill_color_red AS VARCHAR) + ', ' + CAST(body_fill_color_green AS VARCHAR) + ', ' + CAST(body_fill_color_blue AS VARCHAR) + ')' AS body_fill_color,
'('+ CAST(root_line_color_red AS VARCHAR) + ', ' + CAST(root_line_color_green AS VARCHAR) + ', ' + CAST(root_line_color_blue AS VARCHAR) + ')' AS root_line_color,
'('+ CAST(root_fill_color_red AS VARCHAR) + ', ' + CAST(root_fill_color_green AS VARCHAR) + ', ' + CAST(root_fill_color_blue AS VARCHAR) + ')' AS root_fill_color
FROM dental_procedure;
GO

CREATE VIEW vw_transaction
AS
SELECT
     t.transaction_id AS transaction_id,
     tt.transaction_type_id AS transaction_type_id,
     tt.descr AS transaction_type,
     transaction_date,
     p.patient_id AS patient_id,
     p.last_name + ', ' + p.first_name AS patient_name,
     dp.descr AS dental_procedure,
     t.tooth_id AS tooth_id,
     th.tooth_code AS tooth_code,
     t.amount AS amount,
     t.userx_id AS userx_id,
     u.username AS username,
     --_____________________________ Root
     dp.root_line_color_red AS root_line_color_red,
     dp.root_line_color_green AS root_line_color_green,
     dp.root_line_color_blue AS root_line_color_blue,
     --
     dp.root_fill_color_red AS root_fill_color_red,
     dp.root_fill_color_green AS root_fill_color_green,
     dp.root_fill_color_blue AS root_fill_color_blue,
     --_____________________________ Body
     dp.body_line_color_red AS body_line_color_red,
     dp.body_line_color_green AS body_line_color_green,
     dp.body_line_color_blue AS body_line_color_blue,
     --
     dp.body_fill_color_red AS body_fill_color_red,
     dp.body_fill_color_green AS body_fill_color_green,
     dp.body_fill_color_blue AS body_fill_color_blue
FROM transactionx t, transaction_type tt, userx u, patient p, dental_procedure dp, tooth th
WHERE t.transaction_type_id = tt.transaction_type_id AND
          t.userx_id = u.userx_id AND
          t.patient_id = p.patient_id AND
          t.dental_procedure_id = dp.dental_procedure_id AND
          t.tooth_id = th.tooth_id;
GO


Problem 2
Create a desktop Window application using Wintempla called TeethX to manage a dental practice. Be sure to select Window Application with toolbar icons. Your application must allow the user to perform the four basic operations in each table in the database.

Basic Operations

  • SELECT (search)
  • INSERT (add a new record)
  • DELETE (delete a record)
  • UPDATE (edit a record)

Table List

  • userx (one point for each operation. Total 4 points.)
  • patient (one point for each operation. Total 4 points.)
  • dental_procedure (one point for each operation. Total 4 points.)
  • transaction_type (one point for each operation. Total 4 points.)
  • transactionx (one point for each operation. Total 4 points.)

TeethX.h
#pragma once //______________________________________ TeethX.h
...
#define TAB_PATIENT 0
#define TAB_PAYMENT 1
#define TAB_PATIENT_CHART 2
#define TAB_PROCEDURE_SETUP 3
#define TAB_USERS 4


Problem 3
Add to your project a new Dialog called LoginDlg to prompt the user for his username and password. The dialog must return a valid userx_id to the Teeth object. You must store the userx_id returned by this dialog in a member variable of the Teeth class. When marco logs in, there are only two tabs available. However, when tommy logs in, all tabs are available.

MarcoLogin

MarcoTeethX

TommyLogin

TommyTeethX

LoginDlg.h
#pragma once //_____________________________________________ LoginDlg.h
#include "resource.h"

class LoginDlg: public Win::Dialog
{
public:
     LoginDlg()
     {
          tryCount = 0;
          userx_id = -1;
     }
     ~LoginDlg()
     {
     }
     int tryCount;
     int userx_id;
private:
     ...
};


TeethX.cpp
void TeethX::Window_Open(Win::Event& e)
{
     //________________________________________________________ Login: get userx_id
     LoginDlg dlg;
     if (dlg.BeginDialog(hWnd) != TRUE)
     {
          this->Destroy();
          return;
     }
     userx_id = dlg.userx_id;
     //________________________________________________________ Get Access info from the userx table
     bool is_active = false;
     bool has_access_patient_info = false;
     bool has_access_users = false;
     bool has_access_payments = false;
     bool has_access_patient_chart = false;
     bool has_access_dental_procedure_setup = false;
     Sql::SqlConnection conn;
     wstring cmd;
     int employee_id = 0;
     try
     {
          //conn.OpenSession(DSN, USERNAME, PASSWORD); //Control Panel>Administrative Tools>Data Sources (ODBC)>Create dsn_myDatabase
          conn.OpenSession(hWnd, CONNECTION_STRING);
          Sys::Format(cmd, L"SELECT is_active, has_access_patient_info, has_access_users, has_access_payments, has_access_patient_chart, has_access_dental_procedure_setup FROM userx WHERE userx_id = %d", userx_id);
          conn.ExecuteSelect(cmd);
          conn.BindColumn(1, is_active);
          conn.BindColumn(2, has_access_patient_info);
          conn.BindColumn(3, has_access_users);
          conn.BindColumn(4, has_access_payments);
          conn.BindColumn(5, has_access_patient_chart);
          conn.BindColumn(6, has_access_dental_procedure_setup);
          if (conn.Fetch() != true)
          {
               this->MessageBox(L"Unable to get user access", L"TeethX", MB_OK | MB_ICONERROR);
               this->Destroy();
               return;
          }
     }
     catch (Sql::SqlException e)
     {
          this->MessageBox(e.GetDescription(), L"TeethX", MB_OK | MB_ICONERROR);
     }
     if (is_active == false)
     {
          this->MessageBox(L"This account is not active", L"TeethX", MB_OK | MB_ICONERROR);
          this->Destroy();
          return;
     }
     //________________________________________________________ tabSelection
     int index = 0;
     if (has_access_patient_info == true) tabSelection.Items.Add(index++, L"Patient", TAB_PATIENT); //Table: patient
     if (has_access_payments == true) tabSelection.Items.Add(index++, L"Payment", TAB_PAYMENT); // Table: transactionx with transation_type = Payment, Discount, or Consolidation
     if (has_access_patient_chart == true) tabSelection.Items.Add(index++, L"Patient Chart", TAB_PATIENT_CHART); //Table: transactionx with transation_type = Dental procedure
     if (has_access_dental_procedure_setup == true) tabSelection.Items.Add(index++, L"Procedure Setup", TAB_PROCEDURE_SETUP); // Table: dental_procedure
     if (has_access_users == true) tabSelection.Items.Add(index++, L"Users", TAB_USERS); // Table: userx

     tabSelection.SelectedIndex = 0;

     ...
}


Problem 4
Add to your project a new Dialog called UserDlg to edit and add users from the userx table. To edit a user you can double click the user or use edit button from the toolbar.

UsersTab

JulyUserEdit

UserDlg.h
#pragma once //_____________________________________________ UserDlg.h
#include "resource.h"

class UserDlg: public Win::Dialog
{
public:
     UserDlg()
     {
          userx_id = -1;
     }
     ~UserDlg()
     {
     }
     int userx_id;
     ...
};

Problem 5
Add to your project a new Dialog called PatientDlg to edit and add patients from the patient table. To edit a patient you can double click the patient or use edit button from the toolbar.

PatientEdit

PatientDlg.h
#pragma once //_____________________________________________ PatientDlg.h
#include "resource.h"

class PatientDlg: public Win::Dialog
{
public:
     PatientDlg()
     {
          patient_id = -1;
     }
     ~PatientDlg()
     {
     }
     int patient_id;
private:
     ...
};

Problem 6
Add to your project a new Dialog called DentalProcedureSetupDlg to edit and add patients from the dental_procedure table. To edit a dental procedure you can double click the dental procedure or use edit button from the toolbar. Be sure to select "Color Text Button" in the properties of the respective buttons as shown.

ProcedureSetupTab

DentalProcedureEdit

ColorTextButton

DentalProcedureSetupDlg.h
#pragma once //_____________________________________________ DentalProcedureSetupDlg.h
#include "resource.h"

class DentalProcedureSetupDlg: public Win::Dialog
{
public:
     DentalProcedureSetupDlg()
     {
          dental_procedure_id = -1;
     }
     ~DentalProcedureSetupDlg()
     {
     }
     int dental_procedure_id;
     Win::ColorDlg colorDialog;
private:
     ...
};

DentalProcedureSetupDlg.cpp
#include "stdafx.h" //_____________________________________________ DentalProcedureSetupDlg.cpp
#include "DentalProcedureSetupDlg.h"

void DentalProcedureSetupDlg::Window_Open(Win::Event& e)
{
     this->Text=L"Dental procedure";
     Sql::SqlConnection conn;
     int root_line_color_red = 0;
     int root_line_color_green = 0;
     int root_line_color_blue = 0;
     //
     int root_fill_color_red = 0;
     int root_fill_color_green = 0;
     int root_fill_color_blue = 0;
     //_____________________________ Body
     int body_line_color_red = 0;
     int body_line_color_green = 0;
     int body_line_color_blue = 0;
     //
     int body_fill_color_red = 0;
     int body_fill_color_green = 0;
     int body_fill_color_blue = 0;
     //
     wstring cmd;
     try
     {
          //conn.OpenSession(DSN, USERNAME, PASSWORD); //Control Panel>Administrative Tools>Data Sources (ODBC)>Create dsn_myDatabase
          conn.OpenSession(hWnd, CONNECTION_STRING);
          if (dental_procedure_id < 0) return;
          Sys::Format(cmd, L"SELECT descr, estimated_cost, root_line_color_red, root_line_color_green, root_line_color_blue, root_fill_color_red, root_fill_color_green, root_fill_color_blue, body_line_color_red, body_line_color_green, body_line_color_blue, body_fill_color_red, body_fill_color_green, body_fill_color_blue FROM dental_procedure WHERE dental_procedure_id=%d", dental_procedure_id);
          conn.ExecuteSelect(cmd);
          tbxDescr.MaxTextLength = 30;
          conn.BindColumn(1, tbxDescr, 128);
          conn.BindColumn(2, tbxEstimated_cost, 128);
          conn.BindColumn(3, root_line_color_red);
          conn.BindColumn(4, root_line_color_green);
          conn.BindColumn(5, root_line_color_blue);
          //
          conn.BindColumn(6, root_fill_color_red);
          conn.BindColumn(7, root_fill_color_green);
          conn.BindColumn(8, root_fill_color_blue);
          //_____________________________ Body
          conn.BindColumn(9, body_line_color_red);
          conn.BindColumn(10, body_line_color_green);
          conn.BindColumn(11, body_line_color_blue);
          //
          conn.BindColumn(12, body_fill_color_red);
          conn.BindColumn(13, body_fill_color_green);
          conn.BindColumn(14, body_fill_color_blue);
          if (conn.Fetch() == false)
          {
               this->MessageBox(L"No data was returned", L"Error", MB_OK);
          }
     }
     catch (Sql::SqlException e)
     {
          this->MessageBox(e.GetDescription(), L"Error", MB_OK | MB_ICONERROR);
     }
     btBodyFillColor.BackColor = RGB(body_fill_color_red, body_fill_color_green, body_fill_color_blue);
     btBodyLineColor.BackColor = RGB(body_line_color_red, body_line_color_green, body_line_color_blue);
     //
     btRootFillColor.BackColor = RGB(root_fill_color_red, root_fill_color_green, root_fill_color_blue);
     btRootLineColor.BackColor = RGB(root_line_color_red, root_line_color_green, root_line_color_blue);
}

void DentalProcedureSetupDlg::btOK_Click(Win::Event& e)
{
     //_____________________________________________________________ Validate
     wregex regexDouble(L"[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?");
     wregex regextbxDescr(L"[A-Za-z0-9]+");
     if (regex_match(tbxDescr.Text, regextbxDescr) == false)
     {
          tbxDescr.ShowBalloonTip(L"Invalid Descr", L"Please provide one or more characters", TTI_ERROR);
          return;
     }
     if (regex_match(tbxEstimated_cost.Text, regexDouble) == false)
     {
          tbxEstimated_cost.ShowBalloonTip(L"Invalid Estimated cost", L"Please provide a floating point value", TTI_ERROR);
          return;
     }
     const int root_line_color_red = GetRValue(btRootLineColor.BackColor);
     const int root_line_color_green = GetGValue(btRootLineColor.BackColor);
     const int root_line_color_blue = GetBValue(btRootLineColor.BackColor);
     //
     const int root_fill_color_red = GetRValue(btRootFillColor.BackColor);
     const int root_fill_color_green = GetGValue(btRootFillColor.BackColor);
     const int root_fill_color_blue = GetBValue(btRootFillColor.BackColor);
     //_____________________________ Body
     const int body_line_color_red = GetRValue(btBodyLineColor.BackColor);
     const int body_line_color_green = GetGValue(btBodyLineColor.BackColor);
     const int body_line_color_blue = GetBValue(btBodyLineColor.BackColor);
     //
     const int body_fill_color_red = GetRValue(btBodyFillColor.BackColor);
     const int body_fill_color_green = GetGValue(btBodyFillColor.BackColor);
     const int body_fill_color_blue = GetBValue(btBodyFillColor.BackColor);

     Sql::StringBuilder sb(L"dental_procedure", L"dental_procedure_id", dental_procedure_id);
     sb.Bind(L"descr", tbxDescr);
     sb.Bind(L"estimated_cost", tbxEstimated_cost);
     sb.BindInt(L"root_line_color_red", root_line_color_red);
     sb.BindInt(L"root_line_color_green", root_line_color_green);
     sb.BindInt(L"root_line_color_blue", root_line_color_blue);
     //
     sb.BindInt(L"root_fill_color_red", root_fill_color_red);
     sb.BindInt(L"root_fill_color_green", root_fill_color_green);
     sb.BindInt(L"root_fill_color_blue", root_fill_color_blue);
     //_____________________________ Body
     sb.BindInt(L"body_line_color_red", body_line_color_red);
     sb.BindInt(L"body_line_color_green", body_line_color_green);
     sb.BindInt(L"body_line_color_blue", body_line_color_blue);
     //
     sb.BindInt(L"body_fill_color_red", body_fill_color_red);
     sb.BindInt(L"body_fill_color_green", body_fill_color_green);
     sb.BindInt(L"body_fill_color_blue", body_fill_color_blue);
     Sql::SqlConnection conn;
     int rows = 0;
     try
     {
          //conn.OpenSession(DSN, USERNAME, PASSWORD); //Control Panel>Administrative Tools>Data Sources (ODBC)>Create dsn_myDatabase
          conn.OpenSession(hWnd, CONNECTION_STRING);
          rows = conn.ExecuteNonQuery(sb.GetString());
          if (rows!=1)
          {
               this->MessageBox(Sys::Convert::ToString(rows), L"Error: number of affected rows", MB_OK | MB_ICONERROR);
               return;
          }
     }
     catch (Sql::SqlException e)
     {
          this->MessageBox(e.GetDescription(), L"Error", MB_OK | MB_ICONERROR);
          return;
     }
     this->EndDialog(TRUE);
}

void DentalProcedureSetupDlg::btCancel_Click(Win::Event& e)
{
     this->EndDialog(FALSE);
}

void DentalProcedureSetupDlg::btBodyLineColor_Click(Win::Event& e)
{
     colorDialog.SelectedColor = btBodyLineColor.BackColor;
     if (colorDialog.BeginDialog(hWnd) == TRUE)
     {
          btBodyLineColor.BackColor = colorDialog.SelectedColor;
     }
}

void DentalProcedureSetupDlg::btBodyLineColor_DrawItem(Win::Event& e)
{
     DRAWITEMSTRUCT * pDrawItem = (DRAWITEMSTRUCT *)e.lParam;
     btBodyLineColor.DrawButton(pDrawItem);
     e.returnValue = TRUE;
}

void DentalProcedureSetupDlg::btBodyFillColor_Click(Win::Event& e)
{
     colorDialog.SelectedColor = btBodyFillColor.BackColor;
     if (colorDialog.BeginDialog(hWnd) == TRUE)
     {
          btBodyFillColor.BackColor = colorDialog.SelectedColor;
     }
}

void DentalProcedureSetupDlg::btBodyFillColor_DrawItem(Win::Event& e)
{
     DRAWITEMSTRUCT * pDrawItem = (DRAWITEMSTRUCT *)e.lParam;
     btBodyFillColor.DrawButton(pDrawItem);
     e.returnValue = TRUE;
}

void DentalProcedureSetupDlg::btRootLineColor_Click(Win::Event& e)
{
     colorDialog.SelectedColor = btRootLineColor.BackColor;
     if (colorDialog.BeginDialog(hWnd) == TRUE)
     {
          btRootLineColor.BackColor = colorDialog.SelectedColor;
     }
}

void DentalProcedureSetupDlg::btRootLineColor_DrawItem(Win::Event& e)
{
     DRAWITEMSTRUCT * pDrawItem = (DRAWITEMSTRUCT *)e.lParam;
     btRootLineColor.DrawButton(pDrawItem);
     e.returnValue = TRUE;
}

void DentalProcedureSetupDlg::btRootFillColor_Click(Win::Event& e)
{
     colorDialog.SelectedColor = btRootFillColor.BackColor;
     if (colorDialog.BeginDialog(hWnd) == TRUE)
     {
          btRootFillColor.BackColor = colorDialog.SelectedColor;
     }
}

void DentalProcedureSetupDlg::btRootFillColor_DrawItem(Win::Event& e)
{
     DRAWITEMSTRUCT * pDrawItem = (DRAWITEMSTRUCT *)e.lParam;
     btRootFillColor.DrawButton(pDrawItem);
     e.returnValue = TRUE;
}


Problem 7
Add to your project a new Dialog called PaymentDlg to edit and add payments from the transactionx table. To edit a payment you can double click the payment or use edit button from the toolbar. To add a payment first you need to select a patient and then add a payment. The next problem will discuss how to select a patient.

PaymentTab

EditPayment

PaymentDlg.h
#pragma once //_____________________________________________ PaymentDlg.h
#include "resource.h"

class PaymentDlg: public Win::Dialog
{
public:
     PaymentDlg()
     {
          transaction_id = -1;
          patient_id = -1;
          userx_id = -1;
     }
     ~PaymentDlg()
     {
     }
     int transaction_id;
     int patient_id;
     int userx_id;
private:
     ...
};

Problem 8
Add to your project a new Dialog called SelectPatientDlg to select a patient from the patient table. You must store the patient_id returned by this dialog in a member variable of the class TeethX.

SelectPatientIcon

SelectPatientDlg

SelectPatientPaymentTab

SelectPatientDlg.h
#pragma once //_____________________________________________ SelectPatientDlg.h
#include "resource.h"

class SelectPatientDlg: public Win::Dialog
{
public:
     SelectPatientDlg()
     {
          patient_id = -1;
     }
     ~SelectPatientDlg()
     {
     }
     int patient_id;
private:
     ...
};

SelectPatientDlg.cpp
...
void SelectPatientDlg::lvPatient_ItemActivate(Win::Event& e)
{
     const int selectedIndex = lvPatient.GetSelectedIndex();
     if (selectedIndex < 0) return;
     patient_id = lvPatient.Items[selectedIndex].Data;
     this->EndDialog(TRUE);
}



Problem 9
Using Corel Draw create two files: tooth_lower.cdr and tooth_upper.cdr as shown. In order to get the tooth at coordinates (0, 0), you must place the tooth at the left top of the page as shown. In the figures below, the body of the tooth is displayed in blue, the root in black and the surrounding rectangle in red. The surrounding rectangle called box will be used to scale the tooth so that it can fit in a custom control, DO NOT PLACE THE BOX COMPLETELY ALIGNED WITH THE PAGE BORDERS, instead place the box a little to the left and to the top as shown. Use the Object Manager in Corel Draw to set the names as shown (Windows > Dockers > Object Manager ).

ToothPosition

ToothSize

ToothObjectManager

tooth_lower

tooth_upper

tooth_lower_svg

tooth_upper_svg

Problem 10
Using Corel Draw export the files: tooth_lower.cdr and tooth_upper.cdr SVG. The copy the SVG file to the folder of your project as shown. To get more information about SVG, see Wintempla > Graphics > Bezier Curves .

ExportSvg

TeethXFolder

Problem 11
From Microsoft Visual Studio add the SVG files (tooth_lower.svg and tooth_upper.svg) as BIN resources see Wintempla > Graphics > Bezier Curves . Remember that a resource is a file that is stored in the executable main file.

AddResource

ImportResource

tooth_lower_inport

BinResource

Problem 12
From Resource View in Microsoft Visual Studio use the Properties View to set the names of the resources as shown: IDR_TOOTH_UPPER and IDR_TOOTH_LOWER.

ResourceId

Problem 13
Add a Custom Control called Tooth to your project. To learn more about Custom Controls see Wintempla > Graphics > Custom Control . The custom control must have the following properties:
  1. Selected: The tooth can be selected or unselected (bool)
  2. Focus: The tooth can receive or lose the focus (bool)
  3. Type: Each adult tooth can be: 1, 2, 3, ..., 32. Each child tooth can be: A, B, C, ..., S (wstring). 0 no tooth.
  4. BodyLineColor: The color used to draw the border of the body of the tooth (COLORREF)
  5. BodyFillColor: The color used to fill the body of the tooth of the tooth (COLORREF)
  6. RootLineColor: The color used to draw the border of the root of the tooth (COLORREF)
  7. RootFillColor: The color used to fill the root of the tooth (COLORREF)

Tooth.h
// Tooth.h
#pragma once
#include "resource.h"

class Tooth: public Win::Window
{
public:
     Tooth();
     ~Tooth();
     //_________________________ Font
     virtual void SetFont(Win::Gdi::Font& font);
     __declspec( property( put=SetFont) ) Win::Gdi::Font& Font;
     //_________________________ Selected
     bool GetSelected();
     void SetSelected(bool selected);
     __declspec( property (get=GetSelected, put=SetSelected)) bool Selected;
     //_________________________ ToothCode: L"A", L"B",..., L"K", L"1", L"2",...L"32"
     wstring GetToothCode();
     void SetToothCode(wstring type);
     __declspec( property (get=GetToothCode, put=SetToothCode)) wstring ToothCode;
     //______________________________ BodyLineColor
     COLORREF GetBodyLineColor();
     void SetBodyLineColor(COLORREF color);
     __declspec( property (get=GetBodyLineColor, put=SetBodyLineColor)) COLORREF BodyLineColor;
     //______________________________ BodyFillColor
     COLORREF GetBodyFillColor();
     void SetBodyFillColor(COLORREF color);
     __declspec( property (get=GetBodyFillColor, put=SetBodyFillColor)) COLORREF BodyFillColor;
     //______________________________ RootLineColor
     COLORREF GetRootLineColor();
     void SetRootLineColor(COLORREF color);
     __declspec( property (get=GetRootLineColor, put=SetRootLineColor)) COLORREF RootLineColor;     
     //______________________________ RootFillColor
     COLORREF GetRootFillColor();
     void SetRootFillColor(COLORREF color);
     __declspec( property (get=GetRootFillColor, put=SetRootFillColor)) COLORREF RootFillColor;
     //______________________________ IsUpper
     bool GetIsUpper();
     void SetIsUpper(bool isUpper);
     __declspec( property (get=GetIsUpper, put=SetIsUpper)) bool IsUpper;
     //
     bool IsEvent(Win::Event& e, int notification);
private:
     bool _selected;
     bool _hasFocus;
     wstring _tooth_code;
     bool _isUpper;
     HFONT _hfont;
     COLORREF _bodyLineColor;
     COLORREF _bodyFillColor;
     COLORREF _rootLineColor;
     COLORREF _rootFillColor;
     //
     vector<Sys::PointF> pointBodyUpper;
     POINT* _pointBodyUpper;
     int _pointBodyCountUpper;
     //
     vector<Sys::PointF> pointBodyLower;
     POINT* _pointBodyLower;
     int _pointBodyCountLower;
     //
     vector<Sys::PointF> pointRootUpper;
     POINT* _pointRootUpper;
     int _pointRootCountUpper;
     //
     vector<Sys::PointF> pointRootLower;
     POINT* _pointRootLower;
     int _pointRootCountLower;
     //
     double _svgWidth;
     double _svgHeight;
     // ___________________________ DOUBLE BUFFERING
     CG::DDBitmap bitmap;
     void OnPaintControl(CG::Gdi& gdi);
     //
     const wchar_t * GetClassName(void){return L"TOOTH";}
     static bool isRegistered;
protected:
     //______ Wintempla GUI manager section begin: DO NOT EDIT AFTER THIS LINE
     void Window_Open(Win::Event& e);
     void Window_Paint(Win::Event& e);
     void Window_Size(Win::Event& e);
     void Window_LButtonDown(Win::Event& e);
     void Window_SetFocus(Win::Event& e);
     void Window_KillFocus(Win::Event& e);
};

Tooth.cpp
// Tooth.cpp
#include "stdafx.h"
#include "Tooth.h"

bool Tooth::isRegistered= false;

Tooth::Tooth()
{     
     if (!this->isRegistered)
     {
          this->RegisterClassEx(
               LoadCursor(NULL, IDC_ARROW),
               (HBRUSH)::GetStockObject(NULL_BRUSH)); // Background is transparent
          this->isRegistered = true;
     }
     _selected = false;
     _hasFocus = false;
     _tooth_code = L"1";
     _isUpper = true;
     _hfont = NULL;
     //
     _bodyLineColor = RGB(70, 70, 70);
     _bodyFillColor = RGB(245, 245, 245);
     _rootLineColor = RGB(70, 70, 70);
     _rootFillColor = RGB(245, 245, 245);
     //
     _pointBodyUpper = NULL;
     _pointBodyCountUpper = 0;
     //
     _pointBodyLower = NULL;
     _pointBodyCountLower = 0;
     //
     _pointRootUpper = NULL;
     _pointRootCountUpper = 0;
     //
     _pointRootLower = NULL;
     _pointRootCountLower = 0;
     //
     _svgWidth = 0.0;
     _svgHeight = 0.0;
}

Tooth::~Tooth()
{
     if (_pointBodyUpper != NULL) delete [] _pointBodyUpper;
     ...
}

void Tooth::Window_Open(Win::Event& e)
{
     const wchar_t* error = NULL;
     //_______________________________________________________________________________ UPPER
     Sys::SvgReader svgUpper;
     error = svgUpper.LoadFromResource(true, this->hInstance, IDR_TOOTH_UPPER);
     if (error != NULL)
     {
          this->MessageBox(error, L"TOOTH_UPPER", MB_OK | MB_ICONERROR);
          return;
     }
     //____________________________________________________ Box
     Sys::PointF position;
     Sys::PointF size;
     if (svgUpper.GetRectangle(L"box", position, size) == false)
     {
          this->MessageBox(L"The box rectangle could not be found", L"Tooth", MB_OK | MB_ICONERROR);
          return;
     }
     // Use the position and size from the SVG to create the rect variable
     _svgWidth = size.x;
     _svgHeight = size.y;
     //________________________________________________ Bezier Body Upper
     wstring type;
     if (svgUpper.GetPathPoints(L"body", pointBodyUpper, type) == false)
     {
          this->MessageBox(L"The body bezier could not be found", L"Tooth", MB_OK | MB_ICONERROR);
          return;
     }
     _pointBodyCountUpper = pointBodyUpper.size();
     _pointBodyUpper = new POINT[_pointBodyCountUpper];
     for(int i = 0; i < _pointBodyCountUpper; i++)
     {
          _pointBodyUpper[i].x = (int)(pointBodyUpper[i].x);
          _pointBodyUpper[i].y = (int)(pointBodyUpper[i].y);
     }

     //________________________________________________ Bezier Root Upper
     if (svgUpper.GetPathPoints(L"root", pointRootUpper, type) == false)
     {
          this->MessageBox(L"The root bezier could not be found", L"Tooth", MB_OK | MB_ICONERROR);
          return;
     }
     _pointRootCountUpper = pointRootUpper.size();
     _pointRootUpper = new POINT[_pointRootCountUpper];
     for(int i = 0; i < _pointRootCountUpper; i++)
     {
          _pointRootUpper[i].x = (int)(pointRootUpper[i].x);
          _pointRootUpper[i].y = (int)(pointRootUpper[i].y);
     }

     //_______________________________________________________________________________ LOWER
     Sys::SvgReader svgLower;
     error = svgLower.LoadFromResource(true, this->hInstance, IDR_TOOTH_LOWER);
     if (error != NULL)
     {
          this->MessageBox(error, L"TOOTH_LOWER", MB_OK | MB_ICONERROR);
          return;
     }
     //________________________________________________ Bezier Body Lower
     if (svgLower.GetPathPoints(L"body", pointBodyLower, type) == false)
     {
          this->MessageBox(L"The body bezier could not be found", L"Tooth", MB_OK | MB_ICONERROR);
          return;
     }
     _pointBodyCountLower = pointBodyLower.size();
     _pointBodyLower = new POINT[_pointBodyCountLower];
     for(int i = 0; i < _pointBodyCountLower; i++)
     {
          _pointBodyLower[i].x = (int)(pointBodyLower[i].x);
          _pointBodyLower[i].y = (int)(pointBodyLower[i].y);
     }
     //________________________________________________ Bezier Root Lower
     if (svgLower.GetPathPoints(L"root", pointRootLower, type) == false)
     {
          this->MessageBox(L"The root bezier could not be found", L"Tooth", MB_OK | MB_ICONERROR);
          return;
     }
     _pointRootCountLower = pointRootLower.size();
     _pointRootLower = new POINT[_pointRootCountLower];
     for(int i = 0; i < _pointRootCountLower; i++)
     {
          _pointRootLower[i].x = (int)(pointRootLower[i].x);
          _pointRootLower[i].y = (int)(pointRootLower[i].y);
     }
}

void Tooth::Window_Paint(Win::Event& e)
{
     CG::Gdi gdi(hWnd, true, false);
     CG::Gdi gdiBitmap(bitmap, gdi.GetRcPaint(), false);
     OnPaintControl(gdiBitmap);
     gdi.DrawDoubleBuffer(bitmap);     
}

void Tooth::OnPaintControl(CG::Gdi& gdi)
{
     RECT rect;

     CG::Pen penSelected(PS_SOLID, 1, RGB(0, 0, 255));
     CG::Brush brushSelected(RGB(220, 220, 255));
     //
     CG::Pen penNormal(PS_SOLID, 1, RGB(220, 220, 220));
     CG::Brush brushNormal(RGB(220, 220, 220));
     //
     CG::Pen penBody(PS_SOLID, 1, _bodyLineColor);
     CG::Brush brushBody(_bodyFillColor);
     //
     CG::Pen penRoot(PS_SOLID, 1, _rootLineColor);
     CG::Brush brushRoot(_rootFillColor);

     rect.left = 0;
     rect.top = 0;
     rect.right = width;
     rect.bottom = height;
     //_____________________________________ Paint the Background
     if (Selected== true)
     {
          gdi.Select(penSelected);
          gdi.Select(brushSelected);
     }
     else
     {
          gdi.Select(penNormal);
          gdi.Select(brushNormal);
     }
     gdi.Rectangle(rect);

     //_____________________________________ Paint the Body
     gdi.Select(penBody);
     if (_isUpper == true)
     {
          gdi.FillPolyBezier(_pointBodyUpper, _pointBodyCountUpper, brushBody);
          gdi.PolyBezier(_pointBodyUpper, _pointBodyCountUpper);
     }
     else
     {
          gdi.FillPolyBezier(_pointBodyLower, _pointBodyCountLower, brushBody);
          gdi.PolyBezier(_pointBodyLower, _pointBodyCountLower);
     }
     //_____________________________________ Paint the Root
     gdi.Select(penRoot);
     if (_isUpper == true)
     {
          gdi.FillPolyBezier(_pointRootUpper, _pointRootCountUpper, brushRoot);
          gdi.PolyBezier(_pointRootUpper, _pointRootCountUpper);
     }
     else
     {
          gdi.FillPolyBezier(_pointRootLower, _pointRootCountLower, brushRoot);
          gdi.PolyBezier(_pointRootLower, _pointRootCountLower);
     }
     //_____________________________________ Paint the tooth Type
     if (_tooth_code.empty() == false)
     {
          gdi.SelectFont__(_hfont);
          gdi.SetBkMode(true);
          gdi.SetTextColor(RGB(0, 0, 0));
          if (Selected == true) gdi.SetTextColor(RGB(0, 0, 255));
          if (Enabled == false) gdi.SetTextColor(RGB(180, 180, 180));
          gdi.TextOut(0, 0, _tooth_code.c_str());
     }
     //_____________________________________ Paint The Focus
     if (_hasFocus == true)
     {
          CG::Pen pen;
          pen.Create(PS_DOT, 1, RGB(50, 50, 50));
          gdi.Select(pen);
          gdi.SelectNullBrush(); // No filling

          rect.left = 0;
          rect.top = 0;
          rect.right = width;
          rect.bottom = height;
          gdi.Rectangle(rect);
     }
}

void Tooth::SetFont(Win::Gdi::Font& font)
{
     _hfont = font.GetHFONT();
     if (hWnd == NULL) return;
     ::InvalidateRect(hWnd, NULL, FALSE);
}

void Tooth::Window_Size(Win::Event& e)
{
     int i;
     bitmap.CreateCompatible(hWnd, width, height);
     //___________________________________________ Find scale
     const double scaleX = width/_svgWidth;
     const double scaleY = height/_svgHeight;
     const double scale = MINIMUM(scaleX, scaleY);
     const double actualWidth = _svgWidth * scale;
     const double actualHeight = _svgHeight * scale;
     const double offsetX = (width - actualWidth)/2.0;
     const double offsetY = (height - actualHeight)/2.0;
     //___________________________________________ Scale and body
     for(i = 0; i < _pointBodyCountUpper; i++)
     {
          _pointBodyUpper[i].x = (int)(pointBodyUpper[i].x*scale + offsetX);
          _pointBodyUpper[i].y = (int)(pointBodyUpper[i].y*scale + offsetY);
     }
     for(i = 0; i < _pointBodyCountLower; i++)
     {
          _pointBodyLower[i].x = (int)(pointBodyLower[i].x*scale + offsetX);
          _pointBodyLower[i].y = (int)(pointBodyLower[i].y*scale + offsetY);
     }
     //___________________________________________ Scale root
     for(i = 0; i < _pointRootCountUpper; i++)
     {
          _pointRootUpper[i].x = (int)(pointRootUpper[i].x*scale + offsetX);
          _pointRootUpper[i].y = (int)(pointRootUpper[i].y*scale + offsetY);
     }
     for(i = 0; i < _pointRootCountLower; i++)
     {
          _pointRootLower[i].x = (int)(pointRootLower[i].x*scale + offsetX);
          _pointRootLower[i].y = (int)(pointRootLower[i].y*scale + offsetY);
     }
}

bool Tooth::IsEvent(Win::Event& e, int notification)
{
     if (e.uMsg!=WM_COMMAND) return false;
     const int id = LOWORD(e.wParam);
     const int notificationd = HIWORD(e.wParam);
     if (id != this->id) return false;
     if (notificationd!=notification) return false;
     return true;
}

void Tooth::Window_LButtonDown(Win::Event& e)
{
     if (Enabled==false) return;
     HWND hWndParent = ::GetParent(hWnd);
     ::SendMessage(hWndParent, WM_COMMAND, MAKEWPARAM(this->id, WIN_CLICK), e.lParam);
     ::SetFocus(hWnd);
}

COLORREF Tooth::GetRootFillColor()
{
     return _rootFillColor;
}

void Tooth::SetRootFillColor(COLORREF color)
{
     if (_rootFillColor == color) return;
     _rootFillColor = color;
     Repaint(NULL, true);
}
...


Problem 14
You must add 32 custom control of the Tooth class to the TeethX class.

TeethXWintempla

TeethX.h
#pragma once //______________________________________ TeethX.h
#include "resource.h"
#include "PatientDlg.h"
#include "Tooth.h"
#include "LoginDlg.h"
#include "SelectPatientDlg.h"
#include "PaymentDlg.h"
#include "DentalProcedureSetupDlg.h"
#include "TransactionDentalProcedureDlg.h"
#include "UserDlg.h"

#define TAB_PATIENT 0
#define TAB_PAYMENT 1
#define TAB_PATIENT_CHART 2
#define TAB_PROCEDURE_SETUP 3
#define TAB_USERS 4
//
#define TOOTH_COUNT 32

class TeethX: public Win::Window
{
public:
     TeethX()
     {
          patient_id = -1;
          userx_id = -1;
          //
          tooth[0] = &customControl1;
          tooth[1] = &customControl2;
          tooth[2] = &customControl3;
          tooth[3] = &customControl4;
          tooth[4] = &customControl5;
          tooth[5] = &customControl6;
          tooth[6] = &customControl7;
          tooth[7] = &customControl8;
          tooth[8] = &customControl9;
          tooth[9] = &customControl10;
          tooth[10] = &customControl11;
          tooth[11] = &customControl12;
          tooth[12] = &customControl13;
          tooth[13] = &customControl14;
          tooth[14] = &customControl15;
          tooth[15] = &customControl16;
          tooth[16] = &customControl17;
          tooth[17] = &customControl18;
          tooth[18] = &customControl19;
          tooth[19] = &customControl20;
          tooth[20] = &customControl21;
          tooth[21] = &customControl22;
          tooth[22] = &customControl23;
          tooth[23] = &customControl24;
          tooth[24] = &customControl25;
          tooth[25] = &customControl26;
          tooth[26] = &customControl27;
          tooth[27] = &customControl28;
          tooth[28] = &customControl29;
          tooth[29] = &customControl30;
          tooth[30] = &customControl31;
          tooth[31] = &customControl32;
     }
     ~TeethX()
     {
     }
     int patient_id; // show all: patient_id = -1
     int userx_id; //
     Tooth* tooth[TOOTH_COUNT];
     void Edit();
     void Delete();
     void RefreshData();
     void UpdatePatientChart();
     const wchar_t * GetClassName(){return L"TEETHX";}
protected:
     //______ Wintempla GUI manager section begin: DO NOT EDIT AFTER THIS LINE
     ...
};


TeethX.cpp
...

void TeethX::Window_Open(Win::Event& e)
{
     ...
     //_______________________________________________ Tooth setup
     wchar_t text[64];
     for(i = 0; i < TOOTH_COUNT; i++)
     {
          tooth[i]->IsUpper = (i < 16);
          _snwprintf_s(text, 64, _TRUNCATE, L"%d", i+1);
          tooth[i]->ToothCode = text;
          tooth[i]->Visible = false;
     }
     RefreshData();
}

void TeethX::RefreshData()
{
     this->toolbMain.EnableButton(IDM_DELETE, false);
     lvData.SetRedraw(false);
     const int view = tabSelection.SelectedData;

     //________________________________________________ Columns
     lvData.Cols.DeleteAll();
     switch(view)
     {
     case TAB_PATIENT:
          ...
          break;
     case TAB_PAYMENT:
     case TAB_PATIENT_CHART:
          ...
          break;
     case TAB_PROCEDURE_SETUP:
          ...
          break;
     case TAB_USERS:
          ...
          break;
     }

     //________________________________________________ Items
     lvData.Items.DeleteAll();
     wstring text;
     switch(view)
     {
     case TAB_PATIENT:
          text = ....
          break;
     case TAB_PAYMENT:
          if (patient_id == -1)
          {
               text = ....
          }
          else
          {
               Sys::Format(text,...
          }
          break;
     case TAB_PATIENT_CHART:
          if (patient_id == -1)
          {
               text = ...
          }
          else
          {
               Sys::Format(text, ...
          }
          break;
     case TAB_PROCEDURE_SETUP:
          text = ...
          break;
     case TAB_USERS:
          text = ...
          break;
     }

     if (text.empty() == true)
     {
          lvData.SetRedraw(true);
          return;
     }
     Sql::SqlConnection conn;
     try
     {
          //conn.OpenSession(DSN, USERNAME, PASSWORD); //Control Panel>Administrative Tools>Data Sources (ODBC)>Create dsn_myDatabase
          conn.OpenSession(hWnd, CONNECTION_STRING);
          conn.ExecuteSelect(text.c_str(), 100, lvData);
     }
     catch (Sql::SqlException e)
     {
          this->MessageBox(e.GetDescription(), L"Error", MB_OK | MB_ICONERROR);
     }
     lvData.SetRedraw(true);
     if (view == TAB_PATIENT_CHART) UpdatePatientChart();
}

void TeethX::UpdatePatientChart()
{
     int i;
     //_____________________________________________ Clear Patient Chart
     for(i = 0; i < TOOTH_COUNT; i++)
     {
          tooth[i]->BodyFillColor = RGB(245, 245, 245);
          tooth[i]->BodyLineColor = RGB(70, 70, 70);
          tooth[i]->RootFillColor = RGB(245, 245, 245);
          tooth[i]->RootLineColor = RGB(70, 70, 70);
     }
     if (patient_id == -1) return;

     int root_line_color_red = 0;
     int root_line_color_green = 0;
     int root_line_color_blue = 0;
     //
     int root_fill_color_red = 0;
     int root_fill_color_green = 0;
     int root_fill_color_blue = 0;
     //_____________________________ Body
     int body_line_color_red = 0;
     int body_line_color_green = 0;
     int body_line_color_blue = 0;
     //
     int body_fill_color_red = 0;
     int body_fill_color_green = 0;
     int body_fill_color_blue = 0;

     Sql::SqlConnection conn;
     wstring tooth_code;
     wstring text;
     int count;
     try
     {
          //conn.OpenSession(DSN, USERNAME, PASSWORD); //Control Panel>Administrative Tools>Data Sources (ODBC)>Create dsn_myDatabase
          conn.OpenSession(hWnd, CONNECTION_STRING);
          for(i = 0; i < TOOTH_COUNT; i++)
          {
               tooth_code = tooth[i]->ToothCode;
               //_______________________________________ Check if the tooth has a procedure
               Sys::Format(text, L"SELECT count(*) FROM vw_transaction WHERE patient_id = %d AND tooth_code = '%s' AND transaction_type_id = 1",
                    patient_id, tooth_code.c_str());
               count = conn.GetInt(text);
               if (count <= 0) continue;
               //_______________________________________ Get Colors (This SQL command must be modified to extract the maximum date that is less or equal than today
               Sys::Format(text, L"SELECT root_line_color_red, root_line_color_green, root_line_color_blue, root_fill_color_red, root_fill_color_green, root_fill_color_blue, body_line_color_red, body_line_color_green, body_line_color_blue, body_fill_color_red, body_fill_color_green, body_fill_color_blue FROM vw_transaction WHERE patient_id = %d AND tooth_code = '%s' AND transaction_type_id = 1",
                    patient_id, tooth_code.c_str());
               conn.ExecuteSelect(text);
               conn.BindColumn(1, root_line_color_red);
               conn.BindColumn(2, root_line_color_red);
               conn.BindColumn(3, root_line_color_blue);
               //
               conn.BindColumn(4, root_fill_color_red);
               conn.BindColumn(5, root_fill_color_green);
               conn.BindColumn(6, root_fill_color_blue);
               //_____________________________ Body
               conn.BindColumn(7, body_line_color_red);
               conn.BindColumn(8, body_line_color_green);
               conn.BindColumn(9, body_line_color_blue);
               //
               conn.BindColumn(10, body_fill_color_red);
               conn.BindColumn(11, body_fill_color_green);
               conn.BindColumn(12, body_fill_color_blue);
               if (conn.Fetch() == true)
               {
                    tooth[i]->BodyFillColor = RGB(body_fill_color_red, body_fill_color_green, body_fill_color_blue);
                    tooth[i]->BodyLineColor = RGB(body_line_color_red, body_line_color_green, body_line_color_blue);
                    tooth[i]->RootFillColor = RGB(root_fill_color_red, root_fill_color_green, root_fill_color_blue);
                    tooth[i]->RootLineColor = RGB(root_line_color_red, root_line_color_green, root_line_color_blue);
               }

          }
     }
     catch (Sql::SqlException e)
     {
          this->MessageBox(e.GetDescription(), L"Error", MB_OK | MB_ICONERROR);
     }
}

void TeethX::tabSelection_SelChange(Win::Event& e)
{
     const int view = tabSelection.SelectedData;
     for(int i = 0; i < TOOTH_COUNT; i++)
     {
          tooth[i]->Visible = (view == TAB_PATIENT_CHART);
     }
     //____________________________________ Adjust Size
     Win::Event event;
     Window_Size(event);
     RefreshData();
}

void TeethX::lvData_ItemActivate(Win::Event& e)
{
     Edit();
}

void TeethX::lvData_ItemChanged(Win::Event& e)
{
     toolbMain.EnableButton(IDM_DELETE, lvData.GetSelectedCount() == 1);
}

void TeethX::lvData_KeyDown(Win::Event& e)
{
     LPNMLVKEYDOWN p = (LPNMLVKEYDOWN) e.lParam;
     if (p->wVKey == VK_DELETE)
     {
          Delete();
     }
}

void TeethX::Cmd_Print(Win::Event& e)
{
     Win::MultipartDocument document;
     document.Create();
     document.AddPart(500, lvData); // 0.5 cm each row

     Win::PrintConnector printConnector;
     printConnector.Print(hWnd, L"TeethX", document);
}

void TeethX::Cmd_Insert(Win::Event& e)
{
     const int view = tabSelection.SelectedData;
     if (view == TAB_PATIENT)
     {
          PatientDlg dlg;
          if (dlg.BeginDialog(hWnd) == TRUE)
          {
               RefreshData();
          }
     }
     else if (view == TAB_PAYMENT)
     {
          PaymentDlg dlg;
          dlg.patient_id = patient_id;
          dlg.userx_id = userx_id;
          if (dlg.BeginDialog(hWnd) == TRUE)
          {
               RefreshData();
          }
     }
     else if (view == TAB_PATIENT_CHART)
     {
          wstring tooth_code;
          for(int i = 0; i < TOOTH_COUNT; i++)
          {
               if (tooth[i]->Selected == true)
               {
                    tooth_code = tooth[i]->ToothCode;
                    break;
               }
          }
          if (tooth_code.empty() == true)
          {
               this->MessageBox(L"Please select a tooth", L"TeethX", MB_OK | MB_ICONINFORMATION);
               return;
          }
          TransactionDentalProcedureDlg dlg;
          dlg.patient_id = patient_id;
          dlg.userx_id = userx_id;
          dlg.tooth_code = tooth_code;
          if (dlg.BeginDialog(hWnd) == TRUE)
          {
               //____________________________ Unselect tooth
               for(int i = 0; i < TOOTH_COUNT; i++)
               {
                    tooth[i]->Selected = false;
               }
               RefreshData();
          }
     }
     else if (view == TAB_PROCEDURE_SETUP)
     {
          DentalProcedureSetupDlg dlg;
          if (dlg.BeginDialog(hWnd) == TRUE)
          {
               RefreshData();
          }
     }
     else if (view == TAB_USERS)
     {
          UserDlg dlg;
          if (dlg.BeginDialog(hWnd) == TRUE)
          {
               RefreshData();
          }
     }
}

void TeethX::Delete()
{
     if (this->MessageBox(L"Are you sure?", L"Teeth", MB_YESNO | MB_ICONQUESTION) != IDYES) return;

     const int view = tabSelection.SelectedData;

     //_______________________________________________________ Extract id from lvData
     const int index = lvData.GetSelectedIndex();
     if (index < 0) return;
     const int id = lvData.Items[index].Data;

     ...
     RefreshData();
}

void TeethX::Cmd_Delete(Win::Event& e)
{
     Delete();
}

void TeethX::Cmd_Edit(Win::Event& e)
{
     Edit();
}

void TeethX::Edit()
{
     //_______________________________________________________ Extract patient_is from lvData
     const int index = lvData.GetSelectedIndex();
     if (index < 0) return;

     const int view = tabSelection.SelectedData;
     //const int view = tabSelection.Items[tabSelection.GetSelected()].Data;
     const int id = lvData.Items[index].Data;

     if (view == TAB_PATIENT)
     {
          PatientDlg dlg;
          dlg.patient_id = id;
          if (dlg.BeginDialog(hWnd) == TRUE)
          {
               RefreshData();
          }
     }
     else if (view == TAB_PAYMENT)
     {
          PaymentDlg dlg;
          dlg.transaction_id = id;
          dlg.patient_id = patient_id;
          dlg.userx_id = userx_id;
          if (dlg.BeginDialog(hWnd) == TRUE)
          {
               RefreshData();
          }
     }
     else if (view == TAB_PATIENT_CHART)
     {
          TransactionDentalProcedureDlg dlg;
          dlg.patient_id = patient_id;
          dlg.userx_id = userx_id;
          dlg.transaction_id = id;
          if (dlg.BeginDialog(hWnd) == TRUE)
          {
               RefreshData();
          }
     }
     else if (view == TAB_PROCEDURE_SETUP)
     {
          DentalProcedureSetupDlg dlg;
          dlg.dental_procedure_id = id;
          if (dlg.BeginDialog(hWnd) == TRUE)
          {
               RefreshData();
          }
     }
     else if (view == TAB_USERS)
     {
          UserDlg dlg;
          dlg.userx_id = id;
          if (dlg.BeginDialog(hWnd) == TRUE)
          {
               RefreshData();
          }
     }
}

void TeethX::Cmd_Copy(Win::Event& e)
{
     lvData.CopyToClipboard();
}

void TeethX::Cmd_Msexcel(Win::Event& e)
{
     Win::FileDlg dlg;
     dlg.Clear();
     dlg.SetFilter(L"MS Excel files (*.xlsx)\0*.xlsx\0\0", 0, L"xlsx");
     if (dlg.BeginDialog(hWnd, L"Save", true))
     {
          lvData.ExportToMsExcel(dlg.GetFileNameFullPath());
     }
}

void TeethX::customControl1_Click(Win::Event& e)
{
     if (customControl1.Selected == true)
     {
          customControl1.Selected = false;
     }
     else
     {
          customControl1.Selected = true;
     }
}

void TeethX::customControl2_Click(Win::Event& e)
{
     if (customControl2.Selected == true)
     {
          customControl2.Selected = false;
     }
     else
     {
          customControl2.Selected = true;
     }
}

...

void TeethX::Cmd_Show_all(Win::Event& e)
{
     patient_id = -1;
     this->Text = L"TeethX";
     RefreshData();
}

void TeethX::Cmd_Select_patient(Win::Event& e)
{
     SelectPatientDlg dlg;
     if (dlg.BeginDialog(hWnd) == TRUE)
     {
          patient_id = dlg.patient_id;
          ...
          RefreshData();
     }
}

void TeethX::Window_Size(Win::Event& e)
{
     const int view = tabSelection.SelectedData;
     const int offset = 4;
     const int half = height/2;
     const int toolbarHeight = 30;
     const int tabHeight = 40;
     const int lvHeight = (view == TAB_PATIENT_CHART) ? half - toolbarHeight - tabHeight - offset : height - toolbarHeight - tabHeight - offset;
     const int toothWidth = (width - 17*offset)/16;
     const int toothHeight = (half-2*offset)/2;
     int x = offset;
     int y = 0;
     toolbMain.Move(x, y, 300, toolbarHeight, true);
     y += toolbarHeight;
     //
     tabSelection.Move(x, y, width - 2*offset, tabHeight, true);
     y += tabHeight;
     //
     lvData.Move(x, y, width - 2*offset, lvHeight, true);
     y += lvHeight + offset;

     if (view == TAB_PATIENT_CHART)
     {
          //__________________________________________________________ Place Teeth
          for(int i = 0; i < TOOTH_COUNT; i++)
          {
               tooth[i]->Move(x, y, toothWidth, toothHeight, true);
               x += toothWidth+offset;
               if (i == TOOTH_COUNT/2 - 1)
               {
                    x = offset;
                    y += toothHeight + offset;
               }
          }
     }
}


Problem 15
Add to your project a new Dialog called TransactionDentalProcedureDlg to edit and add a transaction of the dental procedure type from the transactionx table. To edit a dental procedure transaction you can double click the transaction from the Patient Chart or use edit button from the toolbar. To add a dental procedure transaction: you need to select a patient, a tooth and click the add button from the toolbar. When the user selects a dental procedure the estimated cost of the procedure must be pre-filled in the dialog.

MaciasJosePatientChart

EditDentalProcedure

AddProcedureIcon

SelectToothWarning

Tooth11Selected

Filling

AfterFillingTab

TransactionDentalProcedureDlg.h
#pragma once //_____________________________________________ TransactionDentalProcedureDlg.h
#include "resource.h"

class TransactionDentalProcedureDlg: public Win::Dialog
{
public:
     TransactionDentalProcedureDlg()
     {
          transaction_id = -1;
          patient_id = -1;
          userx_id = -1;
          tooth_id = -1;
     }
     ~TransactionDentalProcedureDlg()
     {
     }
     int transaction_id;
     int patient_id;
     int userx_id;
     wstring tooth_code;
     int tooth_id;
     void UpdateEstimatedCost();
private:
     ...
};

TransactionDentalProcedureDlg.cpp
#include "stdafx.h" //_____________________________________________ TransactionDentalProcedureDlg.cpp
#include "TransactionDentalProcedureDlg.h"

void TransactionDentalProcedureDlg::Window_Open(Win::Event& e)
{
     this->Text=L"Dental Procedure";
     Sql::SqlConnection conn;
     wstring cmd;
     try
     {
          //conn.OpenSession(DSN, USERNAME, PASSWORD); //Control Panel>Administrative Tools>Data Sources (ODBC)>Create dsn_myDatabase
          conn.OpenSession(hWnd, CONNECTION_STRING);
          //_______________________________________ Get ToothID
          if (transaction_id < 0)
          {
               Sys::Format(cmd, L"SELECT tooth_id FROM tooth WHERE tooth_code = '%s'", tooth_code.c_str());

          }
          else
          {
               Sys::Format(cmd, L"SELECT tooth_id FROM transactionx WHERE transaction_id=%d", transaction_id);
          }
          tooth_id = conn.GetInt(cmd);
          //
          conn.ExecuteSelect(L"SELECT dental_procedure_id, descr FROM dental_procedure", 100, ddDental_procedure);
          ddDental_procedure.SelectedIndex = 1;
          UpdateEstimatedCost();
          if (transaction_id < 0) return;
          Sys::Format(cmd, L"SELECT dental_procedure_id, amount, comment FROM transactionx WHERE transaction_id=%d", transaction_id);
          ...
     }
     catch (Sql::SqlException e)
     {
          this->MessageBox(e.GetDescription(), L"Error", MB_OK | MB_ICONERROR);
     }
}

void TransactionDentalProcedureDlg::btOK_Click(Win::Event& e)
{
     ...
     this->EndDialog(TRUE);
}

void TransactionDentalProcedureDlg::btCancel_Click(Win::Event& e)
{
     this->EndDialog(FALSE);
}

void TransactionDentalProcedureDlg::ddDental_procedure_SelChange(Win::Event& e)
{
     UpdateEstimatedCost();
}

void TransactionDentalProcedureDlg::UpdateEstimatedCost()
{
     const int selectedIndex = ddDental_procedure.SelectedIndex;
     if (selectedIndex < 0) return;
     const int dental_procedure_id = ddDental_procedure.Items[selectedIndex].Data;
     Sql::SqlConnection conn;
     wstring cmd;
     try
     {
          //conn.OpenSession(DSN, USERNAME, PASSWORD); //Control Panel>Administrative Tools>Data Sources (ODBC)>Create dsn_myDatabase
          conn.OpenSession(hWnd, CONNECTION_STRING);
          Sys::Format(cmd, L"SELECT estimated_cost FROM dental_procedure WHERE dental_procedure_id = %d", dental_procedure_id);
          tbxAmount.DoubleValue = conn.GetDouble(cmd);
     }
     catch (Sql::SqlException e)
     {
          this->MessageBox(e.GetDescription(), L"Error", MB_OK | MB_ICONERROR);
     }

}

© Copyright 2000-2021 Wintempla selo. All Rights Reserved. Jul 22 2021. Home